﻿using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using CookComputing.XmlRpc;
using System.Collections.Generic;
using System.IO;
using Nop.Services.Blogs;
using Nop.Core.Infrastructure;
using Nop.Core.Domain.Blogs;
using Nop.Services.Customers;

namespace nopCommerce.MetaWebBlogAPI
{
    public class MetaWeblog : XmlRpcService, IMetaWeblog
    {
        IBlogService blogService;
        ICustomerService customerService;

        #region Public Constructors

        public MetaWeblog()
        {
            blogService = EngineContext.Current.Resolve<IBlogService>();
            customerService = EngineContext.Current.Resolve<ICustomerService>();
        }

        #endregion

        #region IMetaWeblog Members

        string IMetaWeblog.AddPost(string blogid, string username, string password,
            Post post, bool publish)
        {
            if (ValidateUser(username, password))
            {
                string id = string.Empty;

                // TODO: Implement your own logic to add the post and set the id
                BlogPost blogpost = new BlogPost();
                blogpost.Title = post.title;
                var user = customerService.GetCustomerByUsername(username);
                //I assume every user has a language
                //blogpost.LanguageId = int.Parse(user.LanguageId.ToString());
                blogpost.LanguageId = 1;
                blogpost.Body = post.description;
                blogpost.AllowComments = true;
                if (post.dateCreated == null || post.dateCreated.Year < 1900)
                {
                    blogpost.CreatedOnUtc = DateTime.Now;
                }
                else
                {
                    blogpost.CreatedOnUtc = post.dateCreated;
                }
                //To Do: Replace with real customer
                int length = 0;
                foreach (string s in post.categories)
                {
                    length++;
                    if (length == post.categories.Length)
                    {
                        blogpost.Tags += s;
                    }
                    else
                    {
                        blogpost.Tags += s + ",";
                    }
                }
                blogService.InsertBlogPost(blogpost);
                id = blogpost.Id.ToString();
                return id;
            }
            throw new XmlRpcFaultException(0, "User is not valid!");
        }

        bool IMetaWeblog.UpdatePost(string postid, string username, string password,
            Post post, bool publish)
        {
            if (ValidateUser(username, password))
            {
                bool result = false;
                var blogpost = blogService.GetBlogPostById(int.Parse(postid));
                if (blogpost != null)
                {
                    blogpost.Title = post.title;
                    var user = customerService.GetCustomerByUsername(username);
                    blogpost.LanguageId = 1;
                    blogpost.Body = post.description;
                    blogpost.AllowComments = true;
                    if (post.dateCreated == null || post.dateCreated.Year < 1900)
                    {
                        blogpost.CreatedOnUtc = DateTime.Now;
                    }
                    else
                    {
                        blogpost.CreatedOnUtc = post.dateCreated;
                    }
                    //To Do: Replace with real customer
                    int length = 0;
                    blogpost.Tags = string.Empty;
                    foreach (string s in post.categories)
                    {
                        length++;
                        if (length == post.categories.Length)
                        {
                            blogpost.Tags += s;
                        }
                        else
                        {
                            blogpost.Tags += s + ",";
                        }
                    }

                    blogService.UpdateBlogPost(blogpost);
                }
                // TODO: Implement your own logic to add the post and set the result

                return result;
            }
            throw new XmlRpcFaultException(0, "User is not valid!");
        }

        Post IMetaWeblog.GetPost(string postid, string username, string password)
        {
            if (ValidateUser(username, password))
            {
                Post post = new Post();
                var nopPost = blogService.GetBlogPostById(int.Parse(postid));
                if (nopPost != null)
                {
                    post.postid = postid;
                    post.title = nopPost.Title;
                    post.description = nopPost.Body;
                    post.dateCreated = nopPost.CreatedOnUtc;
                    //post.userid = nopPost.CreatedById.ToString();
                }
                // TODO: Implement your own logic to update the post and set the post

                return post;
            }
            throw new XmlRpcFaultException(0, "User is not valid!");
        }

        CategoryInfo[] IMetaWeblog.GetCategories(string blogid, string username, string password)
        {
            if (ValidateUser(username, password))
            {
                List<CategoryInfo> categoryInfos = new List<CategoryInfo>();
                //To Do: set to foreign language
                foreach (var a in blogService.GetAllBlogPostTags(7))
                {
                    CategoryInfo c = new CategoryInfo();
                    c.categoryid = Guid.NewGuid().ToString();
                    c.description = a.Name;
                    c.title = a.Name;
                    //replace blog.aspx with your blog page
                    c.htmlUrl = String.Format("blog.aspx/tag={0}", a.Name);
                    c.rssUrl = String.Format("blog.aspx?tag={0}", a.Name);
                    categoryInfos.Add(c);
                }
                // TODO: Implement your own logic to get category info and set the categoryInfos

                return categoryInfos.ToArray();
            }
            throw new XmlRpcFaultException(0, "User is not valid!");
        }

        Post[] IMetaWeblog.GetRecentPosts(string blogid, string username, string password,
            int numberOfPosts)
        {
            if (ValidateUser(username, password))
            {
                List<Post> posts = new List<Post>();

                // TODO: Implement your own logic to get posts and set the posts

                return posts.ToArray();
            }
            throw new XmlRpcFaultException(0, "User is not valid!");
        }

        MediaObjectInfo IMetaWeblog.NewMediaObject(string blogid, string username, string password,
            MediaObject mediaObject)
        {
            if (ValidateUser(username, password))
            {
                //create folder directory
                if (!Directory.Exists(HttpContext.Current.Server.MapPath("~/MetaWebBlogLib")))
                {
                    Directory.CreateDirectory(HttpContext.Current.Server.MapPath("~/MetaWebBlogLib"));
                }

                MediaObjectInfo objectInfo = new MediaObjectInfo();

                //support for image formats
                string newfilename = string.Empty;
                switch (mediaObject.type)
                {
                    case "image/png":
                        newfilename = Guid.NewGuid().ToString() + ".png";
                        break;

                    case "image/gif":
                        newfilename = Guid.NewGuid().ToString() + ".gif";
                        break;

                    case "image/jpg":
                        newfilename = Guid.NewGuid().ToString() + ".jpg";
                        break;
                }

                //I create the new file
                string LPath = HttpContext.Current.Server.MapPath("~/MetaWebBlogLib/" + newfilename);
                FileStream fs = new FileStream(LPath, FileMode.Create, FileAccess.ReadWrite, FileShare.Write);
                fs.Write(mediaObject.bits, 0, mediaObject.bits.Length);
                fs.Flush();
                fs.Close();

                //the URL I give it, however, starts at the root
                objectInfo.url = "MetaWebBlogLib/" + newfilename;
                // TODO: Implement your own logic to add media object and set the objectInfo

                return objectInfo;
            }
            throw new XmlRpcFaultException(0, "User is not valid!");
        }

        bool IMetaWeblog.DeletePost(string key, string postid, string username, string password, bool publish)
        {
            if (ValidateUser(username, password))
            {
                bool result = false;
                var post = blogService.GetBlogPostById(int.Parse(postid));
                blogService.DeleteBlogPost(post);
                // TODO: Implement your own logic to delete the post and set the result

                return result;
            }
            throw new XmlRpcFaultException(0, "User is not valid!");
        }

        BlogInfo[] IMetaWeblog.GetUsersBlogs(string key, string username, string password)
        {
            if (ValidateUser(username, password))
            {
                List<BlogInfo> infoList = new List<BlogInfo>();
                // TODO: Implement your own logic to get blog info objects and set the infoList
                
                BlogInfo bi = new BlogInfo();
                bi.url = "/blog";
                bi.blogid = "1";
                bi.blogName = "nopCommerce Blog";
                infoList.Add(bi);

                return infoList.ToArray();
            }
            throw new XmlRpcFaultException(0, "User is not valid!");
        }

        UserInfo IMetaWeblog.GetUserInfo(string key, string username, string password)
        {
            if (ValidateUser(username, password))
            {
                UserInfo info = new UserInfo();
                var user = customerService.GetCustomerByUsername(username);
                info.userid = user.Id.ToString();
                info.lastname = user.BillingAddress.LastName;
                info.firstname = user.BillingAddress.FirstName;
                info.email = user.Email;
                info.nickname = user.BillingAddress.FirstName;
                info.url = " ";
                // TODO: Implement your own logic to get user info objects and set the info

                return info;
            }
            throw new XmlRpcFaultException(0, "User is not valid!");
        }

        #endregion

        #region Private Methods

        private bool ValidateUser(string username, string password)
        {
            //to be implemented
            return true;
            //StoreMembershipProvider st = new StoreMembershipProvider();
            //return st.ValidateUser(username, password);
        }

        #endregion
    }
}
